package controller

import (
	"github.com/mitchellh/mapstructure"
	"log"
	"mssgserver/constant"
	"mssgserver/db"
	"mssgserver/net"
	"mssgserver/server/login/model"
	"mssgserver/server/login/proto"
	"mssgserver/utils"
	"time"
)

var DefaultAccount = &Account{}

type Account struct {
}

func (a *Account) Router(r *net.Router) {
	g := r.Group("account")
	g.AddRouter("login", a.login)
}

/*
*
登录的方法
具体的实现的逻辑
*/
func (a *Account) login(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
	/**
		1. 用户名 密码 硬件id
		2. 根据用户名 查询user表 得到数据
		3. 进行密码比对，如果密码正确 登录成功
	    4. 保存用户登录记录
		5. 保存用户的最后一次登录信息
	    6. 客户端 需要 一个session，jwt 生成一个加密字符串的加密算法
	    7. 客户端 在发起需要用户登录的行为时，判断用户是否合法
	*/
	loginReq := &proto.LoginReq{}
	loginRes := &proto.LoginRsp{}
	mapstructure.Decode(req.Body.Msg, loginReq)
	//查询用户表的数据
	user := &model.User{}
	ok, err := db.Engine.Table(user).Where("username=?", loginReq.Username).Get(user)
	if err != nil {
		log.Println("用户表查询出错", err)
		return
	}
	if !ok {
		//没有查询到数据
		rsp.Body.Code = constant.UserNotExist
		return
	}
	//进行md5加密
	pwd := utils.Password(loginReq.Password, user.Passcode)
	if pwd != user.Passwd {
		rsp.Body.Code = constant.PwdIncorrect
		return
	}
	//生产jwt
	token, _ := utils.Award(user.UId)
	loginRes.Username = user.Username
	loginRes.UId = user.UId
	loginRes.Session = token
	loginRes.Password = ""
	rsp.Body.Msg = loginRes
	//保存登录记录
	loginHistory := &model.LoginHistory{
		UId:      user.UId,
		CTime:    time.Now(),
		Ip:       loginReq.Ip,
		State:    model.Login,
		Hardware: loginReq.Hardware,
	}
	db.Engine.Table(loginHistory).Insert(loginHistory)
	//更新或者添加最后一次的登录记录
	loginLast := &model.LoginLast{}
	ok, _ = db.Engine.Table(loginLast).Where("uid=?", user.UId).Get(loginLast)
	if ok {
		//更新
		loginLast.Ip = loginReq.Ip
		loginLast.Hardware = loginReq.Hardware
		loginLast.LoginTime = time.Now()
		loginLast.IsLogout = 0
		loginLast.Session = token
		_, err := db.Engine.Table(loginLast).ID(loginLast.Id).Update(loginLast)
		if err != nil {
			log.Println(err)
		}
	} else {
		//插入
		loginLast.Ip = loginReq.Ip
		loginLast.Hardware = loginReq.Hardware
		loginLast.UId = user.UId
		loginLast.LoginTime = time.Now()
		loginLast.IsLogout = 0
		loginLast.Session = token
		_, err := db.Engine.Table(loginLast).Insert(loginLast)
		if err != nil {
			log.Println(err)
		}
	}
	//缓存一下客户端的连接  包的结构体的方法
	conn := req.Conn
	net.Mgr.UserLogin(conn, user.UId, token)
}
